package com.xyh;

import com.xyh.bean.TableInfo;
import com.xyh.builder.*;
import com.xyh.config.DatabaseConfig;
import com.xyh.exception.CodeGeneratorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;

import static java.lang.Thread.sleep;

/**
 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 * ███████╗ █████╗ ███████╗██╗   ██╗     ██╗ █████╗ ██╗   ██╗ █████╗
 * ██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝     ██║██╔══██╗██║   ██║██╔══██╗
 * █████╗  ███████║███████╗ ╚████╔╝      ██║███████║██║   ██║███████║
 * ██╔══╝  ██╔══██║╚════██║  ╚██╔╝  ██   ██║██╔══██║╚██╗ ██╔╝██╔══██║
 * ███████╗██║  ██║███████║   ██║   ╚█████╔╝██║  ██║ ╚████╔╝ ██║  ██║
 * ╚══════╝╚═╝  ╚═╝╚══════╝   ╚═╝    ╚════╝ ╚═╝  ╚═╝  ╚═══╝  ╚═╝  ╚═╝
 * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 *
 * 代码生成器主应用程序
 * @author Hendrix Xie
 * @version 1.0.0
 * @date 2023-05-01
 */
public class RunApplication {
    private static final Logger logger = LoggerFactory.getLogger(RunApplication.class);

    public static void main(String[] args) throws InterruptedException {
        // 打印启动Banner
        printBanner();

        // 检查外部配置文件是否存在
        File externalConfig = new File("./application.properties");
        if (externalConfig.exists()) {
            logger.info("检测到外部配置文件: {}", externalConfig.getAbsolutePath());
            // 设置系统属性，优先使用外部配置文件
            System.setProperty("config.file", externalConfig.getAbsolutePath());
        } else {
            logger.warn("未找到外部配置文件，将使用内部默认配置");
        }
        sleep(1000);

        logger.info("开始执行代码生成任务");

        long startTime = System.currentTimeMillis();

        try {
            // 获取数据库表信息
            List<TableInfo> tables = BuilderTable.getTables();

            // 检查是否成功获取到表信息
            if (tables == null || tables.isEmpty()) {
                throw new CodeGeneratorException("无法获取数据库表信息，请检查数据库连接配置");
            }

            logger.info("成功获取{}个表的信息", tables.size());

            // 生成基础文件
            try {
                BuildBase.execute();
                logger.info("基础文件生成成功");
            } catch (Exception e) {
                throw new CodeGeneratorException("基础文件生成失败", e);
            }
            //生成pom
            try{
                BuildEnv.execute();
                logger.info("生成pom.xml文件成功");
            }catch (Exception e){
                logger.error("生成pom.xml文件失败",e);
            }
            //生成application.properties
            try{
                BuildAppProperties.execute();
                logger.info("生成application.properties文件成功");
            }catch (Exception e){
                logger.error("生成application.properties文件失败",e);
            }

            //生成Spring Boot启动类
            try{
                BuildRunApplication.execute();
                logger.info("生成Spring Boot启动类成功");
            }catch (Exception e){
                logger.error("生成Spring Boot启动类失败",e);
            }

            // 为每个表生成代码
            int successCount = 0;
            for (TableInfo table : tables) {
                try {
                    logger.info("开始生成表 [{}] 的相关代码", table.getTableName());

                    generateTableCode(table);
                    successCount++;
                    logger.info("表 [{}] 的代码生成完成", table.getTableName());
                } catch (Exception e) {
                    logger.error("表 [{}] 的代码生成失败: {}", table.getTableName(), e.getMessage(), e);
                    // 继续处理下一个表，而不是直接退出
                }
            }

            long endTime = System.currentTimeMillis();
            logger.info("代码生成完成! 共处理{}个表, 成功{}个, 耗时{}毫秒",
                    tables.size(), successCount, (endTime - startTime));

            // 打印完成信息
            printCompleteBanner();

        } catch (CodeGeneratorException e) {
            logger.error("代码生成过程中发生错误: {}", e.getMessage(), e);
            System.exit(1);
        } catch (Exception e) {
            logger.error("发生未预期的错误", e);
            System.exit(1);
        } finally {
            // 确保关闭数据库连接池
            DatabaseConfig.closeDataSource();
        }


        new Thread(() -> {
            try {
                String[] lines = {
                        "/*",
                        " *                        _oo0oo_",
                        " *                       o8888888o",
                        " *                       88\" . \"88",
                        " *                       (| -_- |)",
                        " *                       0\\  =  /0",
                        " *                     ___/`---'\\___",
                        " *                   .' \\\\|     |// '.",
                        " *                  / \\\\|||  :  |||// \\",
                        " *                 / _||||| -:- |||||- \\",
                        " *                |   | \\\\\\  - /// |   |",
                        " *                | \\_|  ''\\---/''  |_/ |",
                        " *                \\  .-\\__  '-'  ___/-. /",
                        " *              ___'. .'  /--.--\\  `. .'___",
                        " *           .\"\" '<  `.___\\_<|>_/___.' >' \"\".",
                        " *          | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |",
                        " *          \\  \\ `_.   \\_ __\\ /__ _/   .-` /  /",
                        " *      =====`-.____`.___ \\_____/___.-`___.-'=====",
                        " *                        `=---='",
                        " * ",
                        " * ",
                        " *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
                        " * ",
                        " *            佛祖保佑       永不宕机     永无BUG",
                        " */"
                };

                for (String line : lines) {
                    logger.info(line);
                    Thread.sleep(50);  // 50ms间隔
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();  // 恢复中断状态
                logger.error("佛祖打印被打断", e);
            }
        }).start();

    }

    /**
     * 打印程序启动Banner
     */
    private static void printBanner() {
        try {
            String[] banner = {
                    "==========================================================================",
                    "  ______                       _                        ",
                    " |  ____|                     | |                       ",
                    " | |__   __ _ ___ _   _       | | __ ___   ____ _      ",
                    " |  __| / _` / __| | | |  _   | |/ _` \\ \\ / / _` |     ",
                    " | |___| (_| \\__ \\ |_| | | |__| | (_| |\\ V / (_| |     ",
                    " |______\\__,_|___/\\__, |  \\____/ \\__,_| \\_/ \\__,_|     ",
                    "                   __/ |                               ",
                    "                  |___/                                ",
                    "==========================================================================",
                    ":: EasyJava代码生成器 ::                         (v1.0.0)",
                    ":: 作者: Hendrix Xie                  :: ",
                    "联系QQ:2914213073"
            };

            for (String line : banner) {
                System.out.println(line);
                Thread.sleep(100);
            }
            System.out.println();
            sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

    }

    /**
     * 打印完成Banner
     */
    private static void printCompleteBanner() {
        try {
            String[] banner = {
                    "==========================================================================",
                    "  _____                      _____                      _         _ ",
                    " / ____|                    / ____|                    | |       | |",
                    "| |     ___   __| | ___   | |  __  ___ _ __   ___ _ __| |_ ___  | |",
                    "| |    / _ \\ / _` |/ _ \\  | | |_ |/ _ \\ '_ \\ / _ \\ '__| __/ _ \\ | |",
                    "| |___| (_) | (_| |  __/  | |__| |  __/ | | |  __/ |  | ||  __/ |_|",
                    " \\_____\\___/ \\__,_|\\___|   \\_____|\\___||_| |_|\\___|_|   \\__\\___| (_)",
                    "==========================================================================",
                    ":: 代码生成完成，请刷新pom.xml! ::",
                    ":: 祝您编码愉快! ::"
            };

            for (String line : banner) {
                System.out.println(line);
                Thread.sleep(100);
            }
            sleep(1000);
            System.out.println();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private static void generateTableCode(TableInfo table) throws CodeGeneratorException {
        try {
            BuildPo.execute(table);
            BuildQuery.execute(table);
            BuildMapper.execute(table);
            BuilderMapperXml.execute(table);
            BuildService.execute(table);
            BuildServiceImpl.execute(table);
            BuildController.execute(table);
        } catch (Exception e) {
            throw new CodeGeneratorException("生成表 [" + table.getTableName() + "] 的代码失败", e);
        }
    }
}